package com.pf.log.processor;

import com.google.common.collect.Lists;
import com.pf.common.enums.BaseResultEnum;
import com.pf.common.exception.BusinessException;
import com.pf.common.utils.SpringContextUtils;
import com.pf.log.param.LogExtendLogParam;
import com.pf.log.utils.LogUtils;
import com.pf.rule.mapper.LogMapper;
import com.pf.rule.mapper.entity.LogEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.List;
import java.util.Map;

/**
 * 操作日志记录
 *
 * @author PanFei
 * @version 1.0.0
 * @createTime 2023/6/3 17:45
 */
@Slf4j
public class SimpleLogProcessor<T> {

    ThreadPoolTaskExecutor asyncLogExecutor = SpringContextUtils.getBean(ThreadPoolTaskExecutor.class, "asyncLogExecutor");
    LogMapper logMapper = SpringContextUtils.getBean(LogMapper.class);


    private Map<String, Map<String, String>> dataDictMap;

    public SimpleLogProcessor() {
    }

    public SimpleLogProcessor(Map<String, Map<String, String>> dataDictMap) {
        this.dataDictMap = dataDictMap;
    }


    /**
     * 异步记录新增操作日志
     *
     * @param dataList
     * @param extendLogParam
     */
    public void asyncRecordAddLog(List<T> dataList, LogExtendLogParam extendLogParam) {
        asyncLogExecutor.execute(() -> {
            recordAddLog(dataList, extendLogParam);
        });
    }

    /**
     * 异步记录新增操作日志
     *
     * @param dataList
     */
    public void asyncRecordAddLog(List<T> dataList) {
        asyncLogExecutor.execute(() -> {
            recordAddLog(dataList);
        });
    }

    /**
     * 记录新增操作日志
     *
     * @param dataList
     */
    public void recordAddLog(List<T> dataList) {
        recordAddLog(dataList, null);
    }

    /**
     * 记录新增操作日志
     *
     * @param dataList
     * @param extendLogParam
     */
    public void recordAddLog(List<T> dataList, LogExtendLogParam extendLogParam) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        try {
            List<LogEntity> logList = Lists.newArrayList();
            for (T obj : dataList) {
                LogEntity logEntity = LogUtils.getAddOperationLog(obj, dataDictMap, extendLogParam);
                if (logEntity != null) {
                    logList.add(logEntity);
                }
            }
            if (CollectionUtils.isNotEmpty(logList)) {
                logMapper.batchInsert(logList);
            }
        } catch (Exception e) {
            log.error(">>>>> recordAddLog：error...", e);
            throw new BusinessException(BaseResultEnum.SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 异步记录编辑操作日志信息
     *
     * @param oldDataList
     * @param updatedDataList
     */
    public void asyncRecordModifyLog(List<T> oldDataList, List<T> updatedDataList) {
        asyncLogExecutor.execute(() -> {
            recordModifyLog(oldDataList, updatedDataList, null);
        });
    }

    /**
     * 异步记录编辑操作日志信息
     *
     * @param oldDataList
     * @param updatedDataList
     * @param extendLogParam
     */
    public void asyncRecordModifyLog(List<T> oldDataList, List<T> updatedDataList, LogExtendLogParam extendLogParam) {
        asyncLogExecutor.execute(() -> {
            recordModifyLog(oldDataList, updatedDataList, extendLogParam);
        });
    }

    /**
     * 记录编辑操作日志信息
     *
     * @param oldDataList
     * @param updatedDataList
     * @param extendLogParam
     */
    public void recordModifyLog(List<T> oldDataList, List<T> updatedDataList, LogExtendLogParam extendLogParam) {
        if (CollectionUtils.isEmpty(oldDataList) || CollectionUtils.isEmpty(updatedDataList)) {
            return;
        }
        if (oldDataList.size() != updatedDataList.size()) {
            log.error(">>>>> recordModifyLog：变更前和变更后数据集合个数不一致...");
            throw new BusinessException(BaseResultEnum.PARAM_ERROR.getCode(), "变更前和变更后数据集合个数不一致");
        }
        try {
            List<LogEntity> logList = Lists.newArrayList();
            for (int i = 0; i < updatedDataList.size(); i++) {
                T oldObj = oldDataList.get(i);
                T updatedObj = updatedDataList.get(i);
                LogEntity logEntity = LogUtils.getModifyOperationLog(oldObj, updatedObj, dataDictMap, extendLogParam);
                if (logEntity != null) {
                    logList.add(logEntity);
                }
            }
            if (CollectionUtils.isNotEmpty(logList)) {
                logMapper.batchInsert(logList);
            }
        } catch (Exception e) {
            log.error(">>>>> recordModifyLog：error...", e);
            throw new BusinessException(BaseResultEnum.SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 记录删除操作日志
     *
     * @param dataList
     */
    public void recordDeleteLog(List<T> dataList) {
        recordDeleteLog(dataList, null);
    }

    /**
     * 记录删除操作日志
     *
     * @param dataList
     * @param extendLogParam
     */
    public void recordDeleteLog(List<T> dataList, LogExtendLogParam extendLogParam) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        try {
            List<LogEntity> logList = Lists.newArrayList();
            for (T dataObj : dataList) {
                LogEntity logEntity = LogUtils.getDeleteOrRecoverOperationLog(dataObj, true, extendLogParam);
                if (logEntity != null) {
                    logList.add(logEntity);
                }
            }
            if (CollectionUtils.isNotEmpty(logList)) {
                logMapper.batchInsert(logList);
            }
        } catch (Exception e) {
            log.error(">>>>> recordDeleteLog：error...", e);
            throw new BusinessException(BaseResultEnum.SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 记录删除操作历史记录
     *
     * @param clazz
     * @param businessIdList
     */
    public void recordDeleteLog(Class<T> clazz, List<String> businessIdList) {
        recordDeleteLog(clazz, businessIdList, null);
    }

    /**
     * 记录删除操作历史记录
     *
     * @param clazz
     * @param businessIdList
     * @param extendLogParam
     */
    public void recordDeleteLog(Class<T> clazz, List<String> businessIdList, LogExtendLogParam extendLogParam) {
        if (clazz == null || CollectionUtils.isEmpty(businessIdList)) {
            return;
        }
        try {
            List<LogEntity> logList = Lists.newArrayList();
            for (String businessId : businessIdList) {
                LogEntity logEntity = LogUtils.getDeleteOrRecoverOperationLog(clazz, businessId, true, extendLogParam);
                if (logEntity != null) {
                    logList.add(logEntity);
                }
            }
            if (CollectionUtils.isNotEmpty(logList)) {
                logMapper.batchInsert(logList);
            }
        } catch (Exception e) {
            log.error(">>>>> recordDeleteLog：error...", e);
            throw new BusinessException(BaseResultEnum.SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 记录恢复操作日志
     *
     * @param dataList
     */
    public void recordRecoverLog(List<T> dataList) {
        recordRecoverLog(dataList, null);
    }

    /**
     * 记录恢复操作日志
     *
     * @param dataList
     * @param extendLogParam
     */
    public void recordRecoverLog(List<T> dataList, LogExtendLogParam extendLogParam) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        try {
            List<LogEntity> logList = Lists.newArrayList();
            for (T dataObj : dataList) {
                LogEntity logEntity = LogUtils.getDeleteOrRecoverOperationLog(dataObj, false, extendLogParam);
                if (logEntity != null) {
                    logList.add(logEntity);
                }
            }
            if (CollectionUtils.isNotEmpty(logList)) {
                logMapper.batchInsert(logList);
            }
        } catch (Exception e) {
            log.error(">>>>> recordRecoverLog：error...", e);
            throw new BusinessException(BaseResultEnum.SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 记录删除恢复历史记录
     *
     * @param clazz
     * @param businessIdList
     */
    public void recordRecoverLog(Class<T> clazz, List<String> businessIdList) {
        recordRecoverLog(clazz, businessIdList, null);
    }

    /**
     * 记录删除操作历史记录
     *
     * @param clazz
     * @param businessIdList
     * @param extendLogParam
     */
    public void recordRecoverLog(Class<T> clazz, List<String> businessIdList, LogExtendLogParam extendLogParam) {
        if (clazz == null || CollectionUtils.isEmpty(businessIdList)) {
            return;
        }
        try {
            List<LogEntity> logList = Lists.newArrayList();
            for (String businessId : businessIdList) {
                LogEntity logEntity = LogUtils.getDeleteOrRecoverOperationLog(clazz, businessId, false, extendLogParam);
                if (logEntity != null) {
                    logList.add(logEntity);
                }
            }
            if (CollectionUtils.isNotEmpty(logList)) {
                logMapper.batchInsert(logList);
            }
        } catch (Exception e) {
            log.error(">>>>> recordRecoverLog：error...", e);
            throw new BusinessException(BaseResultEnum.SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }
}
